package com.konsung.presenter.impl;


import android.text.TextUtils;

import com.konsung.bean.MeasureDataBean;
import com.konsung.bean.PatientBean;
import com.konsung.greendaoUtil.GreenDaoManager;
import com.konsung.greendaoUtil.MeasureDataBeanDao;
import com.konsung.greendaoUtil.PatientBeanDao;
import com.konsung.healthfile.R;
import com.konsung.kslibrary.base.BasePresenter;
import com.konsung.presenter.HealthFilePresenter;
import com.konsung.provide.ProviderWriter;
import com.konsung.ui.HealthFileActivity;
import com.konsung.ui.HealthReportActivity;
import com.konsung.ui.defineview.LoadingDialog;
import com.konsung.util.DBDataUtil;
import com.konsung.util.SpUtils;
import com.konsung.util.ToastUtils;
import com.konsung.util.UiUtils;
import com.konsung.util.constant.GlobalConstant;

import org.greenrobot.greendao.query.QueryBuilder;
import org.greenrobot.greendao.query.WhereCondition;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 逻辑实现类
 */

public class HealthFilePresenterImpl extends BasePresenter<HealthFileActivity> implements
        HealthFilePresenter.Presenter {

    @Override
    public List<PatientBean> getAllPatientBean(int start, int length) {
        PatientBeanDao patientBeanDao = GreenDaoManager.getPatientDao(mvpView);
        QueryBuilder<PatientBean> queryBuilder = patientBeanDao.queryBuilder();
        List<PatientBean> list = queryBuilder.orderDesc(PatientBeanDao.Properties.AddDate)
                .offset(start).limit(length)
                .build()
                .forCurrentThread().list();
        return list == null ? new ArrayList<PatientBean>() : list;
    }

    @Override
    public List<PatientBean> getPatientBean(String condition, Date start, Date stop
            , int uploadState, int sex, int startIndex, int length, boolean isQuery) {
        List<PatientBean> listTemp = new ArrayList<>(); //中间存储器
        SimpleDateFormat sdf = UiUtils.getDateFormat(UiUtils.DateState.SHORT);
        try {
            PatientBeanDao patientBeanDao = GreenDaoManager.getPatientDao(mvpView);
            //由于偶发下拉加载不出数据，再此处进行dao缓存清理
            patientBeanDao.detachAll();
            List<PatientBean> patientBeanList;
            if (isQuery) {
                //点击查询
                //查询条件只有是姓名或者身份证号
                // 按照条件查询。
                WhereCondition like1 = PatientBeanDao.Properties.Idcard.like("%"
                        + condition + "%");
                WhereCondition like2 = PatientBeanDao.Properties.Name.like("%"
                        + condition + "%");
                patientBeanList = patientBeanDao.queryBuilder()
                        .orderDesc(PatientBeanDao.Properties.AddDate)
                        .offset(startIndex)
                        .limit(length)
                        .whereOr(like1, like2)
                        .build()
                        .forCurrentThread()
                        .list();
                listTemp.addAll(patientBeanList);
            } else {
                QueryBuilder queryBuilder = patientBeanDao.queryBuilder();
                //点击筛选
                start = start == null ? new Date(0, 1, 1) : start;
                //结束时间加一天，以确保查询到结束时间当天的所有数据
                Date date = sdf.parse(sdf.format(stop));
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                cal.add(Calendar.DATE, 1);
                stop = cal.getTime();
                long startTime = start.getTime();
                long stopTime = stop.getTime();
                // 按照条件查询
                //条件一 ：是否上传
                //条件二：性别
                if (sex > 0) {
                    queryBuilder.where(PatientBeanDao.Properties.Sex.eq(sex));
                }
                if (uploadState == 1) {
                    //未上传
                    queryBuilder.where(PatientBeanDao.Properties.IsUploadAll.eq(false));
                } else if (uploadState == 2) {
                    //已上传
                    queryBuilder.where(PatientBeanDao.Properties.IsUploadAll.eq(true));
                }

                queryBuilder.join(MeasureDataBean.class, MeasureDataBeanDao.Properties.PatientId)
                        .where(MeasureDataBeanDao.Properties.MeasureTime.ge(startTime));

                queryBuilder.join(MeasureDataBean.class, MeasureDataBeanDao.Properties.PatientId)
                        .where(MeasureDataBeanDao.Properties.MeasureTime.le(stopTime));

                queryBuilder.orderDesc(PatientBeanDao.Properties.AddDate);
                queryBuilder.offset(startIndex);
                queryBuilder.limit(length);
                queryBuilder.distinct();
                patientBeanList = queryBuilder.list();
                listTemp.addAll(patientBeanList);
            }
            return listTemp;
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    @Override
    public void deletePatient(final List<String> deletePatient, final boolean isAllSelected,
            final String condition, final Date start, final Date stop, final int sex
            , final int uploadState, final boolean isQuery, final LoadingDialog dialog) {
        final String currentUuid = getCurrentIdCard();
        final PatientBeanDao patientDao = GreenDaoManager.getPatientDao(mvpView);
        final MeasureDataBeanDao measureDataDao = GreenDaoManager.getMeasureDao(mvpView);
        UiUtils.postShortThread(new Runnable() {
            @Override
            public void run() {
                if (isAllSelected) { //全选状态下，对没有选中的居民进行隔离不删除
                    List<PatientBean> allPatient;
                    if (isQuery) {
                        //查询下数据
                        if (condition == null) { //当前居民列表显示的是所有居民
                            allPatient = patientDao.queryBuilder().listLazy();
                        } else { //当前居民列表显示的是按照条件搜索出来的居民
                            allPatient = getPatientBeanLazy(condition, start, stop,
                                    0, Integer.MAX_VALUE);
                        }
                    } else {
                        //筛选下数据
                        allPatient = getPatientBean(condition, start
                                , stop, uploadState, sex, 0, Integer.MAX_VALUE
                                , false);
                    }
                    final List<PatientBean> notDeletePatient = mvpView.notDeletePatient();
                    // 全选状态下且没有过滤掉不删除的居民
                    if (notDeletePatient == null || notDeletePatient.size() == 0) {
                        // TODO 删除公卫数据
                        ProviderWriter.deleteAllHealthFile(mvpView);
                        patientDao.deleteInTx(allPatient);
                        measureDataDao.deleteInTx(getMeasureDataByPatient(allPatient));
                        List<String> idCardList = new ArrayList<>();
                        if (allPatient != null && allPatient.size() > 0) {
                            for (PatientBean patientBean : allPatient) {
                                idCardList.add(patientBean.getIdcard());
                            }
                        }
                        if (idCardList.contains(currentUuid)) {
                            UiUtils.setCurrentPatient("");
                            mvpView.initMeasureData();
                        }
                        allPatient.clear();
                    } else {
                        final ArrayList<String> deletePatientUuid = new ArrayList<>();
                        final ArrayList<String> deleteIdCard = new ArrayList<>();
                        for (PatientBean patient : allPatient) {
                            deletePatientUuid.add(patient.getIdcard());
                            deleteIdCard.add(patient.getIdcard());
                        }
                        allPatient.clear();
                        final ArrayList<String> notDeletePatientUuid = new ArrayList<>();
                        for (PatientBean patient : notDeletePatient) {
                            notDeletePatientUuid.add(patient.getIdcard());
                            deleteIdCard.remove(patient.getIdcard());
                        }
                        // TODO 删除公卫数据
                        for (String idcard : deleteIdCard) {
                            ProviderWriter.deleteHealthFile(mvpView, idcard, "-1");
                        }
                        //过滤掉不需要删除的居民
                        deletePatientUuid.removeAll(notDeletePatientUuid);
                        int size = deletePatientUuid.size();
                        //分多次删除，避免内存溢出,不采用 deleteInTx(List)函数，该函数会导致一些游标问题
                        for (int i = 0; i <= size; i += 20) {
                            int length = i + 20 > size ? size : i + 20;
                            //测量数据的idCard绑定居民的Uuid
                            WhereCondition measureWhere = MeasureDataBeanDao.Properties.Idcard
                                    .in(deletePatientUuid.subList(i, length));
                            WhereCondition patientWhere = PatientBeanDao.Properties.Idcard
                                    .in(deletePatientUuid.subList(i, length));
                            measureDataDao.queryBuilder()
                                    .where(measureWhere)
                                    .buildDelete()
                                    .executeDeleteWithoutDetachingEntities();
                            patientDao.queryBuilder()
                                    .where(patientWhere)
                                    .buildDelete()
                                    .executeDeleteWithoutDetachingEntities();
                        }

                        deletePatientUuid.clear();
                        //不包含当前居民，则当前居民被删除
                        if (!notDeletePatientUuid.contains(currentUuid)) {
                            UiUtils.setCurrentPatient("");
                            mvpView.initMeasureData();
                        }
                    }
                    //全选删除数据，进行所有数据删除，再刷新显示过滤不删出的数据
                    UiUtils.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtils.showShortToast(R.string.delete_success);
                            if (mvpView != null) {
                                mvpView.refreshPatient(notDeletePatient);
                            }
                        }
                    });
                } else {
                    //非全选状态下，对选中的居民进行删除
                    final List<PatientBean> patientBeen = patientDao.queryBuilder()
                            .where(PatientBeanDao.Properties.Idcard.in(deletePatient))
                            .build()
                            .forCurrentThread()
                            .list();
                    List<MeasureDataBean> measureDataBeen = measureDataDao.queryBuilder()
                            .where(MeasureDataBeanDao.Properties.Idcard.in(deletePatient))
                            .build()
                            .forCurrentThread()
                            .list();
                    for (PatientBean patient : patientBeen) {
                        // TODO 删除公卫数据
                        ProviderWriter.deleteHealthFile(mvpView, patient.getIdcard(), "-1");
                    }
                    patientDao.deleteInTx(patientBeen);
                    measureDataDao.deleteInTx(measureDataBeen);
                    if (deletePatient.contains(currentUuid)) { //包含当前居民时，删除当前居民
                        UiUtils.setCurrentPatient("");
                        mvpView.initMeasureData();
                    }
                    UiUtils.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtils.showShortToast(R.string.delete_success);
                            if (mvpView != null) {
                                mvpView.deletePatient(deletePatient);
                            }
                        }
                    });
                }
            }
        });
    }

    /**
     *
     * @param listPatient 用户集合
     * @return 测量数据集合
     */
    private List<MeasureDataBean> getMeasureDataByPatient(List<PatientBean> listPatient) {
        List<MeasureDataBean> measureDataBeanList = new ArrayList<>();
        MeasureDataBeanDao measureDataBeanDao = GreenDaoManager.getMeasureDao(getMvpView());
        if (listPatient != null && listPatient.size() > 0) {
            for (PatientBean patientBean : listPatient) {
                String idCard = patientBean.getIdcard();
                List<MeasureDataBean> list = measureDataBeanDao.queryBuilder()
                        .where(MeasureDataBeanDao.Properties.Idcard.eq(idCard)).list();
                if (list != null && list.size() > 0) {
                    measureDataBeanList.addAll(list);
                }
            }
        }
        return measureDataBeanList;
    }


    /**
     * 子线程查询当前居民最新测量数据，主线程更新UI
     * @param tempContent 查询条件
     * @param tempStart 起始时间
     * @param tempStop 结束时间
     */
    @Override
    public void getNewestMeasureData(final String tempContent, final Date tempStart,
            final Date tempStop) {
        UiUtils.postShortThread(new Runnable() {
            @Override
            public void run() {
                MeasureDataBeanDao measureDataDao = GreenDaoManager.getMeasureDao(mvpView);
                final String patientSize = getPatientSize(tempContent, tempStart, tempStop);
                String idcard = getCurrentIdCard();
                MeasureDataBean measureDataBean = null;
                if (!TextUtils.isEmpty(idcard)) {
                    List<MeasureDataBean> query = measureDataDao
                            .queryBuilder()
                            .orderDesc(MeasureDataBeanDao.Properties.MeasureTime)
                            .where(MeasureDataBeanDao.Properties.Idcard.eq(idcard))
                            .build()
                            .forCurrentThread()
                            .list();
                    UiUtils.setMeasureDataBeen(query);
                    if (query != null && query.size() > 0) {
                        measureDataBean = query.get(0);
                        query.clear();
                    }
                }
                final MeasureDataBean finalMeasureDataBean = measureDataBean;
                final PatientBean currentPatient = getCurrentPatient();
                UiUtils.setCurrent(currentPatient);
                final long allPatientSize = getAllPatientSize();
                UiUtils.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mvpView != null) {
                            mvpView.initMeasureData(finalMeasureDataBean, allPatientSize,
                                    currentPatient, patientSize);
                        }
                    }
                });
            }
        });
    }

    @Override
    public String getMeasureValue(int value) {
        if (value == GlobalConstant.INVALID_DATA) {
            return UiUtils.getString(R.string.invalid_data);
        }
        return value / GlobalConstant.INT_FACTOR + "";
    }

    @Override
    public List<MeasureDataBean> getAllMeasureData() {
        MeasureDataBeanDao measureDataDao = GreenDaoManager.getMeasureDao(mvpView);
        String idCard = getCurrentIdCard();
        return measureDataDao.queryBuilder()
                .orderDesc(MeasureDataBeanDao.Properties.MeasureTime)
                .where(MeasureDataBeanDao.Properties.Idcard.eq(idCard))
                .build()
                .forCurrentThread()
                .list();
    }

    @Override
    public PatientBean getCurrentPatient() {
        String idCard = getCurrentIdCard();
        if (!TextUtils.isEmpty(idCard)) {
            PatientBeanDao patientDao = GreenDaoManager.getPatientDao(mvpView);
            List<PatientBean> list = patientDao.queryBuilder().where(PatientBeanDao.Properties
                    .Idcard.eq(idCard))
                    .build()
                    .forCurrentThread().list();
            if (list != null && list.size() > 0) {
                return list.get(0);
            }
        }
        return null;
    }

    @Override
    public String getPatientSize(String condition, Date start, Date stop) {

        try {
            PatientBeanDao patientDao = GreenDaoManager.getPatientDao(mvpView);
            WhereCondition like1 = PatientBeanDao.Properties.Idcard
                    .like("%" + condition + "%");
            WhereCondition like2 = PatientBeanDao.Properties.Name
                    .like("%" + condition + "%");
            long size;
            // 都为空表示查询所有
            if (start == null && stop == null && condition.trim().length() == 0) {
                size = patientDao.queryBuilder().count();
            } else if (start == null && stop == null) {
                // 按照条件查询。

                size = patientDao.queryBuilder()
                        .whereOr(like1, like2).count();
            } else {
                start = start == null ? new Date(0, 1, 1) : start;
                //结束时间加一天，以确保查询到结束时间当天的所有数据
                if (stop != null) {
                    SimpleDateFormat dateFormat = UiUtils.getDateFormat(UiUtils.DateState.SHORT);
                    Date date = dateFormat.parse(dateFormat.format(stop));
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    cal.add(Calendar.DATE, 1);
                    stop = cal.getTime();
                }
                stop = stop == null ? new Date() : stop;
                // 查询内容为空，查询日期内的数据
                if (condition == null || condition.trim().length() == 0) {
                    size = patientDao.queryBuilder()
                            .where(PatientBeanDao.Properties.CrimeMeasureDate
                            .between(start.getTime(), stop.getTime()))
                            .count();
                } else {
                    // 按照条件查询。
                    size = patientDao.queryBuilder()
                            .whereOr(like1, like2)
                            .where(PatientBeanDao.Properties.CrimeMeasureDate
                            .between(start.getTime(), stop.getTime()))
                            .count();
                }
            }
            return size + "";
        } catch (Exception e) {
            e.printStackTrace();
            return "0";
        }
    }

    @Override
    public String getPatientSizeInSelect(int sex, int upload, Date start, Date stop) {
        long size;
        PatientBeanDao patientDao = GreenDaoManager.getPatientDao(mvpView);
        QueryBuilder queryBuilder = patientDao.queryBuilder();
        //点击筛选
        start = start == null ? new Date(0, 1, 1) : start;
        //结束时间加一天，以确保查询到结束时间当天的所有数据
        Calendar cal = Calendar.getInstance();
        cal.setTime(stop);
        cal.add(Calendar.DATE, 1);
        stop = cal.getTime();
        long startTime = start.getTime();
        long stopTime = stop.getTime();
        // 按照条件查询
        //条件一 ：是否上传
        //条件二：性别
        if (sex > 0) {
            queryBuilder.where(PatientBeanDao.Properties.Sex.eq(sex));
        }
        if (upload == 1) {
            //未上传
            queryBuilder.where(PatientBeanDao.Properties.IsUploadAll.eq(false));
        } else if (upload == 2) {
            //已上传
            queryBuilder.where(PatientBeanDao.Properties.IsUploadAll.eq(true));
        }

        queryBuilder.join(MeasureDataBean.class, MeasureDataBeanDao.Properties.PatientId)
                .where(MeasureDataBeanDao.Properties.MeasureTime.ge(startTime));

        queryBuilder.join(MeasureDataBean.class, MeasureDataBeanDao.Properties.PatientId)
                .where(MeasureDataBeanDao.Properties.MeasureTime.le(stopTime));
        queryBuilder.distinct();
        size = queryBuilder.buildCursor().query().getCount();
        return size + "";
    }

    @Override
    public long getAllPatientSize() {
        String patientSize = getPatientSize("", null, null);
        return Long.valueOf(patientSize);
    }

    @Override
    public void initReportData() {
        UiUtils.postShortThread(new Runnable() {
            @Override
            public void run() {
                PatientBean patientBean = getCurrentPatient();
                UiUtils.setCurrent(patientBean);
                if (patientBean != null) {
                    final List<MeasureDataBean> list = getAllMeasureData();
                    UiUtils.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mvpView != null) {
                                if (list != null && list.size() > 0) {
                                    mvpView.showReport(HealthReportActivity.ReportState.SHOW_DATA,
                                            list);
                                } else {
                                    mvpView.showReport(HealthReportActivity.ReportState
                                            .EMPTY_MEASURE, null);
                                }
                            }
                        }
                    });
                } else {
                    UiUtils.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mvpView != null) {
                                mvpView.showReport(HealthReportActivity.ReportState.EMPTY_PATIENT,
                                        null);
                            }
                        }
                    });
                }
            }
        });
    }

    @Override
    public void switchValue() {
        PatientBeanDao dao = GreenDaoManager.getPatientDao(mvpView);
        List<PatientBean> beanList = dao.queryBuilder().list();
        if (beanList != null && beanList.size() > 0) {
            for (PatientBean patientBean : beanList) {
                //从低版本升级过来的数据的数据上否全部上传字段进行赋值
                DBDataUtil.updatePatientUploadState(mvpView, patientBean.getIdcard());
                List<MeasureDataBean> measureDataBeanList = GreenDaoManager.getMeasureDao(mvpView)
                        .queryBuilder()
                        .where(MeasureDataBeanDao.Properties.Idcard.eq(patientBean.getIdcard()))
                        .list();
                if (measureDataBeanList != null && measureDataBeanList.size() > 0) {
                    for (MeasureDataBean measureDataBean : measureDataBeanList) {
                        //低版本升级过来的用户表和测量表进行数据关联
                        measureDataBean.setPatientId(patientBean.getId());
                        GreenDaoManager.getMeasureDao(mvpView).update(measureDataBean);
                    }
                }
            }
        }
    }

    /**
     * 根据条件查询居民
     * @param condition 查询条件
     * @param start 起始时间
     * @param stop 结束时间
     * @param startIndex 起始位置
     * @param length 最大长度数据
     * @return LazyList<PatientBean>
     */
    public List<PatientBean> getPatientBeanLazy(String condition, Date start, Date stop,
            int startIndex, int length) {
        try {
            PatientBeanDao patientBeanDao = GreenDaoManager.getPatientDao(mvpView);
            List<PatientBean> patientBeanList;
            // 都为空表示查询所有
            if (start == null && stop == null && condition.trim().length() == 0) {
                patientBeanList = patientBeanDao.queryBuilder()
                        .offset(startIndex).limit(length)
                        .build()
                        .forCurrentThread().list();
            } else if (start == null && stop == null) {
                // 按照条件查询。
                WhereCondition like1 = PatientBeanDao.Properties.Idcard.like("%" + condition + "%");
                WhereCondition like2 = PatientBeanDao.Properties.Name.like("%" + condition + "%");
                patientBeanList = patientBeanDao.queryBuilder()
                        .orderDesc(PatientBeanDao.Properties.AddDate)
                        .offset(startIndex)
                        .limit(length)
                        .whereOr(like1, like2)
                        .build()
                        .forCurrentThread()
                        .list();
            } else {
                start = start == null ? new Date(0, 1, 1) : start;
                //结束时间加一天，以确保查询到结束时间当天的所有数据
                if (stop != null) {
                    SimpleDateFormat dateFormat = UiUtils.getDateFormat(UiUtils.DateState.SHORT);
                    Date date = dateFormat.parse(dateFormat.format(stop));
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(date);
                    cal.add(Calendar.DATE, 1);
                    stop = cal.getTime();
                }
                stop = stop == null ? new Date() : stop;
                // 查询内容为空，查询日期内的数据
                if (condition == null || condition.trim().length() == 0) {
                    patientBeanList = patientBeanDao.queryBuilder()
                            .orderDesc(PatientBeanDao.Properties.AddDate)
                            .offset(startIndex)
                            .limit(length)
                            .where(PatientBeanDao.Properties.CrimeMeasureDate
                            .between(start.getTime(), stop.getTime()))
                            .build()
                            .forCurrentThread()
                            .list();
                } else {
                    // 按照条件查询。
                    WhereCondition like1 = PatientBeanDao.Properties.Idcard
                            .like("%" + condition + "%");
                    WhereCondition like2 = PatientBeanDao.Properties.Name
                            .like("%" + condition + "%");
                    patientBeanList = patientBeanDao.queryBuilder().orderDesc()
                            .orderDesc(PatientBeanDao.Properties.AddDate)
                            .offset(startIndex)
                            .limit(length)
                            .where(PatientBeanDao.Properties.CrimeMeasureDate
                            .between(start.getTime(), stop.getTime()))
                            .whereOr(like1, like2)
                            .build()
                            .forCurrentThread()
                            .list();
                }
            }
            return patientBeanList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取当前居民的身份证
     * @return 身份证
     */
    private String getCurrentIdCard() {
        return SpUtils.getSp(mvpView, GlobalConstant.APP_CONFIG, GlobalConstant
                .CURRENT_PATIENT, "");
    }
}
